﻿using System;
using System.Collections;
using System.Collections.Generic;
//using System.Linq;
using System.Data;
using System.IO; 
//using System.Text;
using System.Xml.Serialization;
using System.Xml;
using System.Windows.Forms;

namespace Release
{   ///<remarks>
    ///for the configure class, this class would have the complete data structure of a configuration file.
    ///a instance of this class will existed in the whole life of the application. managing the configurations.
    ///this class will include two sub classes. 
    ///
    /// one is info_proj. this class manages data of one project, if we 
    ///got two, we make 2 instances.
    ///
    /// another is rel_xml. this one is resposible for the xml read and write.
    /// 
    /// </para>
    ///</remarks>
    public class Configure
    {
        public String str_folder_path;
        public String str_file;
        public string act_proj_name;
        public string auto_sync_flag;
        ArrayList list_projs = new ArrayList();       //manages all the available proj info.

        public class info_proj
        {
            public String records_file;
            public String proj_name;
            public ArrayList src_folders = new ArrayList();
            public ArrayList tgt_folders = new ArrayList();
            public Boolean auto_sync;
            public int sync_hour;
            public int sync_minute;
            public Boolean auto_sync_pattern;
            public string sync_pattern;

            public info_proj(){  }
            public info_proj(string proj_name)
            {
                this.proj_name = proj_name;
                if (proj_name == "BMW_NBT")
                {
                    this.records_file = "BMW_NBT.txt";
                }
                else
                {
                    this.records_file = "BMW_Entry.txt";
                }
            }
            public void add_src_folder(string folder)
            {
                this.src_folders.Add(folder);
                //return this.src_folders;
            }
            public Boolean del_src_folder(string folder)
            {
                try
                {
                    this.src_folders.Remove(folder);
                    return true;
                }
                catch (Exception e)
                {
                    return false;
                }
            }
            public void add_tgt_folder(string folder)
            {
                this.tgt_folders.Add(folder);
            }
            public Boolean del_tgt_folder(string folder)
            {
                try
                {
                    this.tgt_folders.Remove(folder);
                    return true;
                }
                catch (Exception e)
                {
                    return false;
                }
            }
        }
        public enum proj_pool { 
            BMW_NBT,
            BMW_Entry
        }
        public Configure() {
            this.act_proj_name = "BMW_Entry";
            this.str_folder_path = Directory.GetCurrentDirectory();
            this.str_file = "config.xml";
            this.auto_sync_flag = "0";
        }

        public Boolean write_new_cfg(){
            try {
                if (!File.Exists(this.str_file)) {
                    File.Create(this.str_file).Close();
                }
                
                XmlDocument myxml = new XmlDocument();
                myxml.CreateXmlDeclaration("1.0", "utf-8", "yes");
                //myxml.Load(this.str_file);
                XmlNode root = myxml.CreateElement("release_Check");
                XmlElement gen_ele = myxml.CreateElement("settings");
                //gen_ele.SetAttribute("general", "")
                XmlElement act_pro_ele = myxml.CreateElement("active_project");
                XmlElement auto_flag = myxml.CreateElement("auto_sync");
                
                act_pro_ele.InnerText = this.act_proj_name;
                auto_flag.InnerText = this.auto_sync_flag;
                gen_ele.AppendChild(act_pro_ele);
                gen_ele.AppendChild(auto_flag);
                root.AppendChild(gen_ele);

                foreach (info_proj p in this.list_projs)
                {
                    XmlElement proj_ele = myxml.CreateElement("project");
                    proj_ele.SetAttribute("project_name", p.proj_name);

                    XmlElement src_ele = myxml.CreateElement("source_folders");
                    src_ele.SetAttribute("type", "1");
                    foreach (string s in p.src_folders) {
                        if (s == null || s == "")
                        {
                            continue;
                        }
                        else {
                            XmlElement src_dir_ele = myxml.CreateElement("dir");
                            src_dir_ele.InnerText = s;
                            src_ele.AppendChild(src_dir_ele);
                        }
                    }
                    proj_ele.AppendChild(src_ele );

                    XmlElement tgt_ele = myxml.CreateElement("target_folders");
                    tgt_ele.SetAttribute("type", "2");
                    foreach (string s in p.tgt_folders) {
                        if (s == null || s == "")
                        {
                            continue;
                        }
                        else {
                            XmlElement tgt_dir_ele = myxml.CreateElement("dir");
                            tgt_dir_ele.InnerText = s;
                            tgt_ele.AppendChild(tgt_dir_ele);
                        }
                    }
                    proj_ele.AppendChild(tgt_ele);

                    if (p.auto_sync) {
                        XmlElement auto_sync_ele = myxml.CreateElement("auto_sync");
                        auto_sync_ele.SetAttribute("value", p.auto_sync.ToString());
                        XmlElement sync_time_ele = myxml.CreateElement("time");
                        sync_time_ele.InnerText = p.sync_hour.ToString("00") + ":" + p.sync_minute.ToString("00");
                        auto_sync_ele.AppendChild(sync_time_ele);
                        XmlElement sync_pattern_ele = myxml.CreateElement("pattern");
                        sync_pattern_ele.InnerText = p.sync_pattern;
                        auto_sync_ele.AppendChild(sync_pattern_ele);
                        proj_ele.AppendChild(auto_sync_ele);
                    }
                    
                    root.AppendChild(proj_ele);
                    myxml.AppendChild(root);
                    myxml.Save(this.str_file);
                }
                myxml = null;
                return true;
            }catch(Exception e){
                MessageBox.Show(e.Message);
                return false;
            }

        }
        public Boolean read_cfg() {
             try{
                XmlDocument myxml = new XmlDocument();
                myxml.Load(this.str_file);
                //XmlNode root = myxml.SelectSingleNode("release_check");
                XmlNode root = myxml.SelectSingleNode("/release_Check");
                XmlNodeList root_list = root.ChildNodes;
                foreach (XmlNode xn1 in root_list) {
                    XmlElement xe = (XmlElement)xn1;
                    if (xe.HasAttribute("project_name"))
                    {
                        info_proj tmp_proj = new info_proj(xe.GetAttribute("project_name"));
                        // we filtered out the project settings.
                        XmlNodeList list1 = xe.ChildNodes;
                        foreach (XmlNode xn2 in list1)
                        {
                            XmlElement xe1 = (XmlElement)xn2;
                            if (xe1.GetAttribute("type") == "1")
                            {
                                if (xe1.HasChildNodes)
                                {
                                    foreach (XmlNode x in xe1.ChildNodes)
                                    {
                                        tmp_proj.add_src_folder(x.InnerText);
                                    }
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            else if (xe1.GetAttribute("type") == "2")
                            {
                                if (xe1.HasChildNodes)
                                {
                                    foreach (XmlNode x in xe1.ChildNodes)
                                    {
                                        tmp_proj.add_tgt_folder(x.InnerText);
                                    }
                                }
                                else
                                {
                                    continue;
                                }
                            }
                            else {
                                tmp_proj.auto_sync = Convert.ToBoolean(xe1.GetAttribute("value"));
                                if (tmp_proj.auto_sync) {
                                    foreach (XmlNode x in xe1.ChildNodes) {
                                        if (x.Name == "time")
                                        {
                                            tmp_proj.sync_hour = Convert.ToInt32(x.InnerText.Split(':')[0]);
                                            tmp_proj.sync_minute = Convert.ToInt32(x.InnerText.Split(':')[1]);
                                        }
                                        else {
                                            if (x.InnerText != "")
                                            {
                                                tmp_proj.auto_sync_pattern = true;
                                                tmp_proj.sync_pattern = x.InnerText;
                                            }
                                            else {
                                                tmp_proj.auto_sync_pattern = false;
                                                tmp_proj.sync_pattern = "";
                                            }
                                        }                                  
                                    }
                                }
                            }
                        }

                        this.list_projs.Add(tmp_proj);
                        tmp_proj = null;
                    }
                    else {
                        foreach (XmlNode xn3 in xe.ChildNodes) {
                            if (xn3.Name == "active_project")
                            {
                                this.act_proj_name = xn3.InnerText;
                            }
                            else {
                                this.auto_sync_flag = xn3.InnerText;
                            }

                        }  
                    } 
                }

                return true;
            }
            catch (Exception e) {
                MessageBox.Show("Error while parse config file: [" + e.Message+ "]\n\nuse default project setting.");
                foreach (int p_code in Enum.GetValues(typeof(proj_pool))) {
                    string p_name = Enum.GetName(typeof(proj_pool), p_code);
                    info_proj porj_mem = new info_proj(p_name);
                    this.update_proj(porj_mem);
                }
                main_form.fale_flag = 1;
                return false;
            }
        }
        public void update_proj(info_proj this_project)
        {
            this.list_projs.Add(this_project);
        }
        public info_proj active_proj() {
            //int i;

            for (int i = 0; i < this.list_projs.Count; i++)
            {
                info_proj p = (info_proj)this.list_projs[i];
                if (p.proj_name == this.act_proj_name)
                {
                    return p;
                }
                else { continue; }
            }
            return null;
        }
        public void del_obj(info_proj proj){
            int index;
            index = 0;
            for (int i = 0; i < this.list_projs.Count; i++) {
                info_proj p = (info_proj)this.list_projs[i];
                if (p.proj_name == proj.proj_name) {
                    index = i;
                    break;
                }
            }
            this.list_projs.RemoveAt(index);
        }
        public void add_obj(info_proj proj) {
            this.list_projs.Add(proj);
        }
    }
}
